package cn.wenhao.javaClassReload.utils;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Rezar
 * @createDate :Apr 8, 2016 5:05:14 PM
 * @desc :
 */
public class CountableThreadPool {

    private int threadNum;
    private AtomicInteger threadAlive = new AtomicInteger(0);
    private ReentrantLock reentrantLock = new ReentrantLock();
    private Condition condition = reentrantLock.newCondition();
    private ExecutorService executorService;

    public CountableThreadPool(int threadNum) {
        this.threadNum = threadNum;
        this.executorService = Executors.newFixedThreadPool(threadNum);
    }

    public CountableThreadPool(int threadNum, ExecutorService executorService) {
        this.threadNum = threadNum;
        this.executorService = executorService;
    }

    /**
     * 对任务进行执行
     * 
     * @param runnable
     */
    public void execute(final Runnable runnable) {
        if (threadAlive.get() >= this.threadNum) {
            try {
                this.reentrantLock.lock();
                while (threadAlive.get() >= this.threadNum) {
                    this.condition.await();
                }
                this.threadAlive.incrementAndGet();
            } catch (InterruptedException e) {
            } finally {
                this.reentrantLock.unlock();
            }
        }
        this.executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    runnable.run();
                } catch (Exception e) {
                } finally {
                    try {
                        CountableThreadPool.this.reentrantLock.lock();
                        CountableThreadPool.this.threadAlive.decrementAndGet();
                        condition.signal();
                    } catch (Exception e) {
                    } finally {
                        CountableThreadPool.this.reentrantLock.unlock();
                    }
                }
            }
        });
    }

    public boolean isShutdown() {
        return executorService.isShutdown();
    }

    public void shutdown() {
        executorService.shutdown();
    }

    public int getThreadNum() {
        return threadNum;
    }

    public void setThreadNum(int threadNum) {
        this.threadNum = threadNum;
    }

    public AtomicInteger getThreadAlive() {
        return threadAlive;
    }

    public void setThreadAlive(AtomicInteger threadAlive) {
        this.threadAlive = threadAlive;
    }

    public ReentrantLock getReentrantLock() {
        return reentrantLock;
    }

    public void setReentrantLock(ReentrantLock reentrantLock) {
        this.reentrantLock = reentrantLock;
    }

    public Condition getCondition() {
        return condition;
    }

    public void setCondition(Condition condition) {
        this.condition = condition;
    }

    public ExecutorService getExecutorService() {
        return executorService;
    }

    public void setExecutorService(ExecutorService executorService) {
        this.executorService = executorService;
    }

}
